Initialise the connection ID when a domain is introduced. This (re)enables
authoremellor@leeni.uk.xensource.com <emellor@leeni.uk.xensource.com>
Fri, 2 Dec 2005 01:34:39 +0000 (01:34 +0000)
committeremellor@leeni.uk.xensource.com <emellor@leeni.uk.xensource.com>
Fri, 2 Dec 2005 01:34:39 +0000 (01:34 +0000)
the permission checking in xenstored.

Default the store permissions to read/write nobody (apart from the privileged
domain).  Create a /local node with these permissions, ready for inheriting by
children.  In Xend, create a /vm node with these permissions too, for the same
reason, and set the permissions on /local/domain/<domid> and each device
backend path to allow the guest domain to access these paths appropriately.

Added xstransact.{set_permissions,SetPermissions,mkdir,Mkdir,complete} as
support facilities.

This closes bug #290.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
tools/python/xen/xend/XendDomain.py
tools/python/xen/xend/XendDomainInfo.py
tools/python/xen/xend/server/DevController.py
tools/python/xen/xend/xenstore/xstransact.py
tools/xenstore/xenstored_core.c
tools/xenstore/xenstored_domain.c

index c6fcddef4f78d91bd0961945df6016d5517d71b1..c5510c8aad5ad39e1a61d3cedb967a9e062d3ca2 100644 (file)
@@ -36,6 +36,7 @@ from xen.xend import XendRoot
 from xen.xend import XendCheckpoint
 from xen.xend.XendError import XendError
 from xen.xend.XendLogging import log
+from xen.xend.xenstore.xstransact import xstransact
 from xen.xend.xenstore.xswatch import xswatch
 
 
@@ -46,6 +47,8 @@ xroot = XendRoot.instance()
 __all__ = [ "XendDomain" ]
 
 PRIV_DOMAIN = 0
+VMROOT = '/vm/'
+
 
 class XendDomain:
     """Index of all domains. Singleton.
@@ -64,6 +67,9 @@ class XendDomain:
     # instance() must be able to return a valid instance of this class even
     # during this initialisation.
     def init(self):
+        xstransact.Mkdir(VMROOT)
+        xstransact.SetPermissions(VMROOT, { 'dom' : PRIV_DOMAIN })
+
         self.domains_lock.acquire()
         try:
             self._add_domain(
index 748db3b3a4339445ea455ef6f82bbf0b23ac6aaf..bb5f8265263c5a2db5d076406339e8974d419496 100644 (file)
@@ -43,7 +43,7 @@ import XendRoot
 from xen.xend.XendBootloader import bootloader
 from xen.xend.XendError import XendError, VmError
 
-from xen.xend.xenstore.xstransact import xstransact
+from xen.xend.xenstore.xstransact import xstransact, complete
 from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain
 from xen.xend.xenstore.xswatch import xswatch
 
@@ -84,8 +84,6 @@ STATE_DOM_SHUTDOWN = 2
 
 SHUTDOWN_TIMEOUT = 30
 
-VMROOT  = '/vm/'
-
 ZOMBIE_PREFIX = 'Zombie-'
 
 """Minimum time between domain restarts in seconds."""
@@ -234,7 +232,7 @@ def recreate(xeninfo, priv):
             log.warn(str(exn))
 
         vm = XendDomainInfo(xeninfo, domid, dompath, True, priv)
-        vm.removeDom()
+        vm.recreateDom()
         vm.removeVm()
         vm.storeVmDetails()
         vm.storeDomDetails()
@@ -385,7 +383,7 @@ class XendDomainInfo:
         else:
             self.domid = None
 
-        self.vmpath  = VMROOT + self.info['uuid']
+        self.vmpath  = XendDomain.VMROOT + self.info['uuid']
         self.dompath = dompath
 
         if augment:
@@ -570,6 +568,14 @@ class XendDomainInfo:
     def removeDom(self, *args):
         return xstransact.Remove(self.dompath, *args)
 
+    def recreateDom(self):
+        complete(self.dompath, lambda t: self._recreateDom(t))
+
+    def _recreateDom(self, t):
+        t.remove()
+        t.mkdir()
+        t.set_permissions({ 'dom' : self.domid })
+
 
     ## private:
 
@@ -1084,7 +1090,7 @@ class XendDomainInfo:
 
         self.dompath = GetDomainPath(self.domid)
 
-        self.removeDom()
+        self.recreateDom()
 
         # Set maximum number of vcpus in domain
         xc.domain_max_vcpus(self.domid, int(self.info['vcpus']))
@@ -1384,7 +1390,7 @@ class XendDomainInfo:
         self.release_devices()
         self.info['name'] = new_name
         self.info['uuid'] = new_uuid
-        self.vmpath = VMROOT + new_uuid
+        self.vmpath = XendDomain.VMROOT + new_uuid
         self.storeVmDetails()
         self.preserve()
 
index fc93b750b77480bfd7c94d1698db72f8e96bd505..94a37843237056e38088f6dfaa9b3c2dcefc593c 100644 (file)
@@ -105,6 +105,13 @@ class DevController:
                 t.remove(frontpath)
                 t.remove(backpath)
 
+                t.mkdir(backpath)
+                import xen.xend.XendDomain
+                t.set_permissions(backpath,
+                                  {'dom': xen.xend.XendDomain.PRIV_DOMAIN },
+                                  {'dom'  : self.vm.getDomid(),
+                                   'read' : True })
+
                 t.write2(frontpath, front)
                 t.write2(backpath,  back)
 
index 1a71035a7cc4826e469c2454fa4fea1797d16cfc..b7a86921856d1875aac846d2a89de4c1e759dca1 100644 (file)
@@ -213,6 +213,27 @@ class xstransact:
                 self._write(key, fmt % val)
 
 
+    def mkdir(self, *args):
+        if len(args) == 0:
+            xshandle().mkdir(self.transaction, self.path)
+        else:
+            for key in args:
+                xshandle().mkdir(self.transaction, self.prependPath(key))
+
+
+    def set_permissions(self, *args):
+        if len(args) == 0:
+            raise TypeError
+        elif isinstance(args[0], str):
+            self.callRebased(args[0], self.set_permissions, *args[1:])
+        else:
+            if not self.path:
+                raise RuntimeError('Cannot set permissions on the root')
+
+            xshandle().set_permissions(self.transaction, self.path,
+                                       list(args))
+
+
     def remove2(self, middlePath, *args):
         self.callRebased(middlePath, self.remove, *args)
 
@@ -245,29 +266,11 @@ class xstransact:
         given path, and return a list composed of the values at each of those
         instead.  This operation is performed inside a transaction.
         """
-        while True:
-            t = cls(path)
-            try:
-                v = t.read(*args)
-                t.abort()
-                return v
-            except:
-                t.abort()
-                raise
-
+        return complete(path, lambda t: t.read(*args))
     Read = classmethod(Read)
 
     def Write(cls, path, *args):
-        while True:
-            t = cls(path)
-            try:
-                t.write(*args)
-                if t.commit():
-                    return
-            except:
-                t.abort()
-                raise
-
+        complete(path, lambda t: t.write(*args))
     Write = classmethod(Write)
 
     def Remove(cls, path, *args):
@@ -275,16 +278,7 @@ class xstransact:
         each further argument as a subpath to the given path, and remove each
         of those instead.  This operation is performed inside a transaction.
         """
-        while True:
-            t = cls(path)
-            try:
-                t.remove(*args)
-                if t.commit():
-                    return
-            except:
-                t.abort()
-                raise
-
+        complete(path, lambda t: t.remove(*args))
     Remove = classmethod(Remove)
 
     def List(cls, path, *args):
@@ -294,16 +288,7 @@ class xstransact:
         and return the cumulative listing of each of those instead.  This
         operation is performed inside a transaction.
         """
-        while True:
-            t = cls(path)
-            try:
-                v = t.list(*args)
-                if t.commit():
-                    return v
-            except:
-                t.abort()
-                raise
-
+        return complete(path, lambda t: t.list(*args))
     List = classmethod(List)
 
     def ListRecursive(cls, path, *args):
@@ -313,40 +298,33 @@ class xstransact:
         subpath to the given path, and return the cumulative listing of each
         of those instead.  This operation is performed inside a transaction.
         """
-        while True:
-            t = cls(path)
-            try:
-                v = t.list_recursive(*args)
-                if t.commit():
-                    return v
-            except:
-                t.abort()
-                raise
-
+        return complete(path, lambda t: t.list_recursive(*args))
     ListRecursive = classmethod(ListRecursive)
 
     def Gather(cls, path, *args):
-        while True:
-            t = cls(path)
-            try:
-                v = t.gather(*args)
-                if t.commit():
-                    return v
-            except:
-                t.abort()
-                raise
-
+        return complete(path, lambda t: t.gather(*args))
     Gather = classmethod(Gather)
 
     def Store(cls, path, *args):
-        while True:
-            t = cls(path)
-            try:
-                v = t.store(*args)
-                if t.commit():
-                    return v
-            except:
-                t.abort()
-                raise
-
+        complete(path, lambda t: t.store(*args))
     Store = classmethod(Store)
+
+    def SetPermissions(cls, path, *args):
+        complete(path, lambda t: t.set_permissions(*args))
+    SetPermissions = classmethod(SetPermissions)
+
+    def Mkdir(cls, path, *args):
+        complete(path, lambda t: t.mkdir(*args))
+    Mkdir = classmethod(Mkdir)
+
+
+def complete(path, f):
+    while True:
+        t = xstransact(path)
+        try:
+            result = f(t)
+            if t.commit():
+                return result
+        except:
+            t.abort()
+            raise
index 012a4201977e76fca46c5b899b4dc25c665ba094..863250941a7126947617eb2da4aa0a67a7c8f763 100644 (file)
@@ -1401,7 +1401,7 @@ void dump_connection(void)
 static void manual_node(const char *name, const char *child)
 {
        struct node *node;
-       struct xs_permissions perms = { .id = 0, .perms = XS_PERM_READ };
+       struct xs_permissions perms = { .id = 0, .perms = XS_PERM_NONE };
 
        node = talloc(NULL, struct node);
        node->name = name;
@@ -1442,6 +1442,7 @@ static void setup_structure(void)
                   the balloon driver, this can be fatal.
                */
                internal_rm("/local");
+               manual_node("/", "local");
        }
        else {
                tdb_ctx = tdb_open(tdbname, 7919, TDB_FLAGS, O_RDWR|O_CREAT,
index 47683558e49d2d7232f7c747c4eb62fe685110b5..353ef9b7ac3dc15a8325d419c02bfb05975a2455 100644 (file)
@@ -287,6 +287,7 @@ static struct domain *new_domain(void *context, unsigned int domid,
 
        domain->conn = new_connection(writechn, readchn);
        domain->conn->domain = domain;
+       domain->conn->id = domid;
 
        domain->remote_port = port;
        domain->mfn = mfn;